#ifndef CAMERA_DRIVER_H
#define CAMERA_DRIVER_H
#include <GxIAPI.h>
#include <exception>
#include <list>
#include <vector>
#include <string>
#include <fstream>
#include <atomic>
#include <chrono>
#include "ThreadSafeQueue.h"
#include "CameraCollegeZeroCopy.h"
#include "FrameData.h"
#include "SaveFile.h"
#include "MuliThreadSave.h"
#include <wx/event.h>
#include <sstream>
#include <future>
#include <functional>
#include <wx/image.h>
#include <wx/thread.h>
#include "PixelFormat.h"

wxDECLARE_EVENT(EVT_FILE_ERROR, wxCommandEvent);

enum class DeviceLinkType
{
	USB2_0,
	Network,
	USB3_0,
	Unknow
};
struct DeviceInf
{
	std::string VendorName;  //厂家名称
	std::string ModelName; //设备类型名称
	std::string SN; //设备序列号
	std::string DisplayName; //设备展示名称
	std::string DeviceID; //设备唯一标识
	std::string UserID; //用户自定义名称
	DeviceLinkType deviceLinkType; //设备连接类型
};


class cameraDriverException : public std::exception
{
public:
	cameraDriverException(GX_STATUS status);
  cameraDriverException(std::string str);
	virtual const char* what() const throw();
private:
  bool userMsg;
  std::string msg;
	GX_STATUS _status;
};

class cameraDriver
//控制驱动程序，用于管理相机
{
public:
	enum class CameraOpenMode
	{
		INDEX,
		SN,
		IP,
		MAC
	};

	class cameraDevice
	//控制相机设备
	{
	public:
		cameraDevice(std::string device, CameraOpenMode mode, wxEvtHandler* evtHandler,int _wxID);
		~cameraDevice();
		//删除拷贝构造函数
		cameraDevice(const cameraDevice&) = delete;
		cameraDevice& operator=(const cameraDevice&) = delete;
		//图像采集控制
		void ResetTimestamp();
		void StartCollegeImage();
		void StopCollegeImage();
		bool GetCollegeImageStatus();
		void SetImageSavePath(std::string path);
		std::string StartSaveImage();
		void StopSaveImage();
		bool GetSaveImageStatus();
		void SetEvtHandler(wxEvtHandler* c);
		void SetImageFPSRate(long fps);
		void SetImageFPSControl(bool status);
		//采集参数控制
		void SetExposureTime(double time);
		double GetExposureTime();
		int64_t GetSensorHeight();
		int64_t GetSensorWidth();
		void SetImageHeight(int64_t value);
		void SetImageWidth(int64_t value);
		int64_t GetImageHeight();
		int64_t GetImageWidth();
		void SetImageOffsetX(int64_t value);
		void SetImageOffsetY(int64_t value);
		int64_t GetImageOffsetX();
		int64_t GetImageOffsetY();
		double GetCollegeFrameRate();
		void SetLinkLimit(bool value);
		int64_t GetLinkSpeed();
		void SetTriggerMode(bool value);
		bool GetTriggerMode();
    pixelFormat GetImageFormat();
    void SetImageFormat(pixelFormat format);
		//统计控制
		void ClearCounter();
		unsigned int GetUnableSaveImageNum();
		unsigned int GetReceiveImageNum();
		unsigned int GetHandleTime();
		unsigned int GetQueueLength();
		//压缩控制
		void SetCmpAcceleration(int value);
	private:
		//0拷贝图像采集
		CameraCollegeZeroCopy* zero_copyCollege=nullptr;
		//图像保存控制
		//SaveFile saveFile;
		MuliThreadSave mtSave;
		//设备控制句柄
		GX_DEV_HANDLE hDevice;
		std::atomic<bool> ImageCollegeStatus; //就是把图像显示出来，用这个标志位控制
		std::atomic<bool> ImageSaveStatus;
		std::string ImageSavePath;
		friend void GX_STDC OnFrameCallbackFun(GX_FRAME_CALLBACK_PARAM* pFrame);
		//图像队列
		ThreadSafeQueue<FrameData> ImageQueue; //默认缓冲区大小1000
		std::atomic<bool> ThreadRunFlag; //控制线程取消标志
		//线程控制函数
		void CreateThread();
		void RecoveryThread();
		void ThreadHandleFrame();
		std::future<void> HandleImageThread;
		std::chrono::steady_clock::time_point lastEmitSignalTime; //上一次发送信号时间，用于控制帧率
		wxEvtHandler* _evtHandler;  //处理事件的UI控件
		int wxID;
		//统计数据
		std::atomic<unsigned int> UnableSaveImageNum;
		std::atomic<unsigned int> ReceiveImageNum;
		std::atomic<unsigned int> HandleTime;
		std::atomic<int> imageHeight;
		std::atomic<int> imageWidth;
		bool UpdateTimestamp=true;
		std::chrono::steady_clock::time_point startCollegeTime;
		bool ImageTiggerMode=false;
    pixelFormat imageFormat;
	};

	cameraDriver();
	~cameraDriver();
	std::vector<DeviceInf> GetDeviceList();
	unsigned GetCameraCount();  //打开的相机数量
	std::list<cameraDevice>::iterator OpenIndexCamera(unsigned device, wxEvtHandler* evtHandler,int wxID); //evtHandler主要用于发送事件
	void CloseCamera(std::list<cameraDevice>::iterator devicePtr);
	void RemoveCamera(std::list<cameraDevice>::iterator);
private:
	std::list<cameraDevice> cameraList;
};

//快捷函数
inline void GXSTAT_check(GX_STATUS status)
{
	if (status != GX_STATUS_SUCCESS)
		throw cameraDriverException(status);
}

#endif // !CAMERA_DRIVER_H
